package com.laker.admin.module.comm.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.laker.admin.framework.exception.BusinessException;
import com.laker.admin.module.comm.entity.CommProduct;
import com.laker.admin.module.comm.entity.CommSpecsRelation;
import com.laker.admin.module.comm.mapper.CommProductMapper;
import com.laker.admin.module.comm.mapper.CommSpecsRelationMapper;
import com.laker.admin.module.comm.service.ICommProductService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.laker.admin.module.inv.entity.InvMessage;
import com.laker.admin.module.inv.mapper.InvMessageMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author laker
 * @since 2024-03-20
 */
@Service
public class CommProductServiceImpl extends ServiceImpl<CommProductMapper, CommProduct> implements ICommProductService {
    @Resource
    private CommProductMapper commProductMapper;

    @Resource
    private InvMessageMapper invMessageMapper;

    @Resource
    private CommSpecsRelationMapper commSpecsRelationMapper;

    @Override
    public <E extends IPage<CommProduct>> E page(E page, Wrapper<CommProduct> queryWrapper) {
        return commProductMapper.selectPage(page, queryWrapper);
    }

    @Override
    public boolean removeById(Serializable id) {
        return SqlHelper.retBool(commProductMapper.deleteById(id));
    }

    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        return CollectionUtils.isEmpty(idList) ? false : SqlHelper.retBool(commProductMapper.deleteBatchIds(idList));
    }

    @Override
    public CommProduct getById(Serializable id) {
        return commProductMapper.selectById(id);
    }

    /**
     * 保存
     * @param entity
     * @return int
     * */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED , rollbackFor = Exception.class)
    public boolean saveOrUpdateProduct(CommProduct entity) {
        boolean result = true;

        if (null == entity) {
            throw new BusinessException("参数为空，内部错误");
        }

//        try {
            TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass);
            Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!", new Object[0]);
            String keyProperty = tableInfo.getKeyProperty();
            Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!", new Object[0]);
            Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty());

            // 新增/更新时同时新增商品库存表
            if (!StringUtils.checkValNull(idVal) && !Objects.isNull(this.getById((Serializable)idVal))) {
                result = this.updateById(entity);
                if (!result) {
                    throw new BusinessException("修改失败");
                }

                // 更新规格
                if (result) {
                    String specsIds = entity.getSpecsIds();
                    String [] specsId = specsIds.split(",");

                    QueryWrapper<CommSpecsRelation> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("ct.comm_id", entity.getCommId());
                    queryWrapper.eq("ct.del_flag", 0L);
                    List<CommSpecsRelation> oldData = commSpecsRelationMapper.selectList(queryWrapper);

                    // 识别删除规格，验证库存，清除库存及关系
                    List<CommSpecsRelation> deleteList = setDeleteLIst(specsId, oldData);
                    // 识别新增规格，插入关系及库存
                    List<Long> insertList = setInsertList(specsId, oldData);

                    if (deleteList.size() > 0) {
                        for (int i = 0; i < deleteList.size(); i++) {
                            CommSpecsRelation commSpecsRelation = deleteList.get(i);
                            // 验证是否可删除
                            Long invSum = commSpecsRelation.getInvSum();
                            if (invSum > 0) {
                                result = false;
                                throw new BusinessException(commSpecsRelation.getCommSpecsName() + "的库存不为0");
                            }

                            // 取消关系、删除库存
                            if (result) {
                                result = commSpecsRelationMapper.deleteById(commSpecsRelation.getCommSpecsRelationId()) > 0;
                                if (!result) {
                                    throw new BusinessException("删除规格失败");
                                }
                            }

                            if (result) {
                                result = invMessageMapper.deleteById(commSpecsRelation.getInvId()) > 0;
                                if (!result) {
                                    throw new BusinessException("删除库存失败");
                                }
                            }
                        }
                    }

                    if (result) {
                        if (insertList.size() > 0) {
                            insertList.forEach(n -> {
                                // 插入规格关系
                                CommSpecsRelation csr = new CommSpecsRelation();
                                csr.setCommSpecsId(n);
                                csr.setCommId(entity.getCommId());
                                commSpecsRelationMapper.insert(csr);

                                // 插入库存
                                InvMessage invMessage = new InvMessage();
                                invMessage.setCommSpecsId(n);
                                invMessage.setCommId(entity.getCommId());
                                invMessage.setCommName(entity.getCommName());
                                invMessage.setInvSum(0L);
                                invMessageMapper.insert(invMessage);
                            });
                        }
                    }
                }
            } else {
                // 插入商品
                result = this.save(entity);
                if (!result) {
                    throw new BusinessException("新增失败");
                }

                String specsIds = entity.getSpecsIds();
                if (result) {
                    String [] specsId = specsIds.split(",");
                    for (int i = 0; i < specsId.length; i++) {
                        String tmpId = specsId[i];
                        // 插入规格关系
                        CommSpecsRelation csr = new CommSpecsRelation();
                        csr.setCommSpecsId(Long.valueOf(tmpId));
                        csr.setCommId(entity.getCommId());
                        result = commSpecsRelationMapper.insert(csr) > 0;
                        if (!result) {
                            throw new BusinessException("新增规格失败");
                        }

                        // 插入库存
                        if (result) {
                            InvMessage invMessage = new InvMessage();
                            invMessage.setCommSpecsId(Long.valueOf(tmpId));
                            invMessage.setCommId(entity.getCommId());
                            invMessage.setCommName(entity.getCommName());
                            invMessage.setInvSum(0L);
                            result = invMessageMapper.insert(invMessage) > 0;
                            if (!result) {
                                throw new BusinessException("新增库存失败");
                            }
                        }
                    }
                }
            }
//        } catch(Exception ex) {
//            ex.printStackTrace();
//            result = false;
//            throw new BusinessException("系统异常");
//        }

        return result;
    }

    private List<Long> setInsertList(String [] specsId, List<CommSpecsRelation> oldData) {
        List<Long> insertList = new ArrayList<>();

        for (int i = 0; i < specsId.length; i++) {
            boolean insertFlag = true;
            for (int j = 0; j < oldData.size(); j++) {
                CommSpecsRelation o = oldData.get(j);
                if (Long.valueOf(specsId[i]).equals(o.getCommSpecsId())) {
                    insertFlag = false;
                    break;
                }
            }

            if (insertFlag) {
                insertList.add(Long.valueOf(specsId[i]));
            }
        }

        return insertList;
    }

    private List<CommSpecsRelation> setDeleteLIst(String [] specsId, List<CommSpecsRelation> oldData) {
        List<CommSpecsRelation> deleteList = new ArrayList<>();

        for (int j = 0; j < oldData.size(); j++) {
            boolean deleteFlag = true;
            CommSpecsRelation o = oldData.get(j);
            for (int i = 0; i < specsId.length; i++) {
                if (Long.valueOf(specsId[i]).equals(o.getCommSpecsId())) {
                    deleteFlag = false;
                    break;
                }
            }

            if (deleteFlag) {
                deleteList.add(o);
            }
        }

        return deleteList;
    }
}
